<?php

namespace App\Model\Dao;

use App\Utils\CustomUtils;
use App\Concern\BaseDao;
use App\Utils\StringUtils;
use Hyperf\Database\Query\Builder;
use Hyperf\DbConnection\Db;
use Hyperf\Utils\Arr;
use Redis;
use App\Utils\RedisUtils;
use Hyperf\Utils\Codec\Json;

/**
 * MchInfoDao
 */
class MchInfoDao extends BaseDao {

    /**
     * 表名常量
     * 联表的时候通过XxxDao::TABLE获取
     */
    const TABLE = "mch_info";

    /**
     * 用户支付token
     */
    const KEY_USER_PAY_TOKEN = 'table:' . self::TABLE . ':token.pay.user';

    // 不支持软删除
    protected $softDelete = null;

    /**
     * 父类中通过静态函数获取表名, 因为不能通过静态常量获取, 这个函数是固定写在子类中的
     */
    public static function table (): string {
        return self::TABLE;
    }

    /**
     * @return \Hyperf\Database\Model\Model|null|object|static
     * 取最后一个
     */
    public function getLast() {
        $builder = DB::table(self::table())
            ->orderBy('createTime', 'desc');
        $data = $builder->first();
        return $data;
    }

    /**
     * @return \Hyperf\Database\Model\Model|null|object|static
     * 取最后一个
     */
    public function getByEmail($email) {
        $builder = DB::table(self::table())
            ->where('email', $email);
        $data = $builder->first();
        return $data;
    }

    /**
     * 排序
     *
     * @param Builder $builder
     * @param array   $params
     *
     * @return Builder|mixed
     */
    protected function _buildOrder (Builder $builder, $params = []) {

        // 通过前端提交的参数排序
        if (Arr::exists($params, "orderBy")) {

            [$prop, $order] = $params["orderBy"];

            if (in_array($order, ["asc", "desc"])) {

                //switch ($prop) {
                //    case "yieldMonth":
                //        $builder->orderBy("main.yieldMonth", $order);
                //        break;
                //    default:
                //        break;
                //}
            }
        }

        // 如果友其他固定的排序需求, 在这里写, 例如按照时间降序
        $builder->orderBy("createTime", "desc");

        // 追加父类的排序, 父类按照ID升序, 保证排序结果唯一
        return parent::_buildOrder($builder, $params);
    }

    /**
     * 查询条件
     *
     * @param $params
     *
     * @return Builder
     */
    protected function _buildQueryString ($params) {

        // 本表一律命名为main
        $main = sprintf("%s AS main", self::TABLE);

        $connTag = sprintf("%s AS connTag", MchTagConnDao::TABLE);

        $builder = DB::table($main);

        if (Arr::exists($params, 'tagIdList')) {
            $builder->join($connTag, 'connTag.mchId', 'main.id');
            $builder->whereIn('connTag.mchTagId', $params['tagIdList']);
            $builder->groupBy(['main.id']);
        }

        $builder->selectRaw(join(',', ['main.*']));

        // CustomUtils::xzxDebug($params);

        // 通过 Arr::exists 来判断是否存在该键, isset不准确
        (Arr::exists($params, "mchNo") && !empty($params['mchNo'])) && $builder->where("main.mchNo", "like", "%{$params['mchNo']}%");
        (Arr::exists($params, "mchName") && !empty($params['mchName'])) && $builder->where("main.mchName", "like", "%{$params['mchName']}%");
        (Arr::exists($params, "mchIdList") && !empty($params["mchIdList"])) && $builder->whereIn("main.id", $params['mchIdList']);
        Arr::exists($params, "createTimeRange") && $builder->whereBetween('main.createTime', $params['createTimeRange']);

        return $builder;
    }

    public function getOption($params) {
        $main = sprintf("%s AS main", self::TABLE);
        $builder = DB::table($main);
        (Arr::exists($params, "mchName") && !empty($params['mchName'])) && $builder->where("main.mchName", "like", "%{$params['mchName']}%");
        return $builder->selectRaw("id as value, mchName as label")->orderByDesc("main.createTime")->get()->toArray();
    }

    /**
     * 生成用户支付凭据token
     * @param $appId
     * @param $ttl
     *
     * @return string
     */
    public function createUserPayToken ($appId, $ttl) {

        $token = strtoupper(sha1(md5($appId) . '*' . StringUtils::uuidV4()));
        $key = self::KEY_USER_PAY_TOKEN . ':' . $appId . ':' . $token;

        RedisUtils::redisResource()->set($key, $token, $ttl);

        return $token;
    }

    /**
     * 校验并删除用户凭据token
     *
     * @param $appId
     * @param $token
     *
     * @return bool
     */
    public function verifyUserPayToken ($appId, $token) {

        $key = self::KEY_USER_PAY_TOKEN . ':' . $appId . ':' . $token;
        $bool = !!RedisUtils::redisResource()->get($key);

        RedisUtils::redisResource()->del($key);

        return $bool;
    }

}
